package luaweb

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"gitee.com/haodreams/golib/autoroute/controller"
	"gitee.com/haodreams/lua/luadb"
	"gitee.com/haodreams/lua/luastring"
	"gitee.com/haodreams/lua/luatask"
	lua "github.com/yuin/gopher-lua"
)

var luaInit func(l *lua.LState)

func SetInitLua(f func(l *lua.LState)) {
	luaInit = f
}

// LuaController 授权相关的操作
type LuaController struct {
	controller.Controller
}

// Tasks 同步任务
func (m *LuaController) Tasks() {
	typ := m.GetParam().GetTrimString("type")
	if m.IsPost() {
		boss := luatask.GetTasks()
		if boss == nil {
			m.Error("没有有效的数据")
		}
		if typ == "async" {
			tasks := boss.AsyncTask.GetTasks()
			m.Page(tasks, nil)
		} else {
			tasks := boss.SyncTask.GetTasks()
			m.Page(tasks, nil)
		}
		return
	}
	m.Display()
}

func (m *LuaController) check(script string) (e string) {
	l := lua.NewState()
	luastring.InitLuaString(l)
	luadb.InitLuaDB(l)
	if luaInit != nil {
		luaInit(l)
	}
	err := l.DoString(script)
	if err != nil {
		msg := strings.ReplaceAll(err.Error(), "\n", "<br/>")
		msg = strings.ReplaceAll(msg, "\t", "&nbsp;&nbsp;")
		return msg
	}
	return ""
}

// Check 检查代码
func (m *LuaController) Check() {
	param := m.GetParam()
	script := param.GetTrimString("lua")
	err := m.check(script)
	if err != "" {
		m.Error(err)
		return
	}
	m.Msg("OK")
}

// Test 测试代码
func (m *LuaController) Test() {
	f := m.GetParam().GetTrimString("func")
	f = "\nfunction MyWarpFunction() \n  return " + f + "\nend"
	script := m.GetParam().GetTrimString("lua")
	script += "\n" + f
	//log.Println(script)
	l := lua.NewState()
	luastring.InitLuaString(l)
	luadb.InitLuaDB(l)
	if luaInit != nil {
		luaInit(l)
	}
	err := l.DoString(script)
	if err != nil {
		msg := strings.ReplaceAll(err.Error(), "\n", "<br/>")
		msg = strings.ReplaceAll(msg, "\t", "&nbsp;&nbsp;")
		m.Error(msg)
		return
	}
	now := time.Now()
	//验证函数是否正确
	err = l.CallByParam(
		lua.P{
			Fn:      l.GetGlobal("MyWarpFunction"),
			NRet:    4,
			Protect: true,
		})
	usedTime := time.Since(now).String()
	if err != nil {
		msg := strings.ReplaceAll(err.Error(), "\n", "<br/>")
		msg = strings.ReplaceAll(msg, "\t", "&nbsp;&nbsp;")
		m.Error(msg + "<br/> Used time:" + usedTime)
		return
	}

	s := bytes.NewBuffer(nil)

	for i := 0; i < l.GetTop(); i++ {
		value := l.Get(i + 1)
		if value.Type().String() == "nil" {
			continue
		}
		log.Println(value.Type().String())
		if value == nil {
			continue
		}
		s.WriteString(fmt.Sprintln(value))
	}
	m.Msg(s.String() + "<br/> Used time:" + usedTime)
}

func (m *LuaController) save(path string) {
	fileName := m.GetParam().GetTrimString("name")
	if fileName == "" {
		m.Error("无效的文件名")
		return
	}
	script := m.GetParam().GetTrimString("lua")
	if strings.HasSuffix(fileName, ".lua") {
		err := m.check(script)
		if err != "" {
			m.Error(err)
			return
		}
	}

	er := os.WriteFile(path+fileName, []byte(script), 0644)
	if er != nil {
		m.Error(er.Error())
		return
	}
	m.Msg("OK")
}

func (m *LuaController) file(path string) {
	path += m.GetParam().GetString("path")
	data, err := os.ReadFile(path)
	if err != nil {
		m.Error(err.Error())
	} else {
		m.Msg(string(data))
	}
}

// Tree 标签
type Tree struct {
	ID       string  `json:"id"`
	Label    string  `json:"label"`
	Icon     string  `json:"icon"`
	Children []*Tree `json:"children"`
}

func (m *LuaController) list(path string) {
	path += m.GetParam().GetString("path")
	fi, err := os.ReadDir(path)
	if err != nil {
		m.Error(err.Error())
		return
	}
	ifs := make([]*Tree, 0, len(fi))
	for _, f := range fi {
		if f.IsDir() {
			continue
		}
		name := f.Name()
		if !strings.HasSuffix(name, ".lua") {
			if !strings.HasSuffix(name, "sync.csv") {
				continue
			}
		}

		inf := new(Tree)
		inf.Label = f.Name()
		inf.ID = f.Name()
		ifs = append(ifs, inf)
	}
	m.JSON(http.StatusOK, ifs)
}

// Save 保存风机代码
func (m *LuaController) Save() {
	m.save("lua/")
}

// File 读取风机源代码
func (m *LuaController) File() {
	m.file("lua/")
}

// List 列出风机计算所有文件
func (m *LuaController) List() {
	if m.IsPost() {
		m.list("lua/")
		return
	}
	m.Display()
}
